package org.alvin.switchserver;

import io.netty.bootstrap.Bootstrap;
import io.netty.buffer.ByteBuf;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import org.alvin.switchserver.ui.models.ServerNodeTableModel;

import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.util.List;
import java.util.Vector;
import java.util.concurrent.TimeUnit;

public class MultiForwardingHandler extends ChannelInboundHandlerAdapter {
    private final EventLoopGroup clientGroup = new NioEventLoopGroup();
    private PropertyChangeSupport uiEventBus;
    private ServerNodeTableModel serverNodeTableModel;

    public MultiForwardingHandler(ServerNodeTableModel serverNodeTableModel, PropertyChangeSupport uiEventBus) {
        this.serverNodeTableModel = serverNodeTableModel;
        this.uiEventBus = uiEventBus;
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        System.out.println("收到数据" + msg);
        for (ServerNode serverNode : serverNodeTableModel.getDataList()) {
            if (serverNode == null) {
                continue;
            }
            Channel clientChannel = serverNode.getChannel();
            clientChannel.writeAndFlush(msg);
            System.out.println("-----转发----");
        }
    }

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        // 初始化客户端连接
        Bootstrap bootstrap = new Bootstrap();
        bootstrap.group(clientGroup)
                .channel(NioSocketChannel.class)
                .handler(new ChannelInitializer<SocketChannel>() {
                    @Override
                    public void initChannel(SocketChannel ch) throws Exception {
                        ch.pipeline()
                                .addLast(new PrintOutputNettyMsgHandler(uiEventBus))
                                .addLast(new ForwardingHandler(ctx, serverNodeTableModel));
                    }
                });
        // 创建对象，并建立重连机制
        for (final ServerNode serverNode : this.serverNodeTableModel.getDataList()) {
            System.out.println("连接服务：" + serverNode.getIp() + ":" + serverNode.getPort());
            ChannelFuture cf = bootstrap.connect(serverNode.getIp(), serverNode.getPort());
            serverNode.setChannel(cf.syncUninterruptibly().channel());
            cf.addListener(new ChannelFutureListener() {
                @Override
                public void operationComplete(ChannelFuture future) throws Exception {
                    if (!future.isSuccess()) {
                        //重连交给后端线程执行
                        future.channel().eventLoop().schedule(() -> {
                            System.out.println("重连服务端...");
                            //判断是否需要重连
                            for (ServerNode reServer : serverNodeTableModel.getDataList()) {
                                if (reServer.equals(serverNode)) {
                                    System.out.println("重连执行==" + reServer.getIp());
                                    try {
                                        ChannelFuture channelFuture = bootstrap.connect(serverNode.getIp(), serverNode.getPort());
                                        channelFuture.addListener(this);
                                        reServer.setChannel(channelFuture.syncUninterruptibly().channel());
                                    } catch (Exception e) {
                                        e.printStackTrace();
                                    }
                                    break;
                                }
                            }
                        }, 10 * 1000, TimeUnit.MILLISECONDS);
                    } else {
                        System.out.println("服务端连接成功...");
                    }
                }
            });
        }

    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        //关闭所有链接
        for (ServerNode serverNode : this.serverNodeTableModel.getDataList()) {
            if (!serverNode.isDefault()) {
                continue;
            }
            Channel clientChannel = serverNode.getChannel();
            if (clientChannel != null && clientChannel.isActive()) {
                clientChannel.close();
            }
        }
        clientGroup.shutdownGracefully();
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        // 异常处理
    }
}


//        this.serverNodeTableModel.addTableModelListener(new TableModelListener() {
//            @Override
//            public void tableChanged(TableModelEvent e) {
//                System.out.println("=======table changed");
//            }
//        });
//
//        uiEventBus.addPropertyChangeListener("addServer", new PropertyChangeListener() {
//            @Override
//            public void propertyChange(PropertyChangeEvent evt) {
////                // 添加服务
////                ServerNode serverNode =    (ServerNode) evt.getNewValue();
////                //添加到列表
////                MultiForwardingHandler.this.serverNodes.add((ServerNode) evt.getNewValue());
////                //建立连接
////                serverNode.setChannel(bootstrap.connect(serverNode.getIp(), serverNode.getPort()).syncUninterruptibly().channel());
//            }
//        });
//
//        uiEventBus.addPropertyChangeListener("delServer", new PropertyChangeListener() {
//            @Override
//            public void propertyChange(PropertyChangeEvent evt) {
//                // 删除服务
//                Integer index = (Integer) evt.getNewValue();
//                ServerNode serverNode = MultiForwardingHandler.this.serverNodes.get(index);
//                // 删除列表
//                MultiForwardingHandler.this.serverNodes.remove(index.intValue());
//                //删除和关闭连接
//                Channel clientChannel = serverNode.getChannel();
//                if (clientChannel != null && clientChannel.isActive()) {
//                    clientChannel.close();
//                }
//            }
//        });
